package com.zpc.myvideoserver.common.security.config;

import com.zpc.myvideoserver.common.security.handler.*;
import com.zpc.myvideoserver.common.security.jwt.JwtAuthenticationFilter;
import com.zpc.myvideoserver.common.security.service.UserDetailServiceImpl;
import io.swagger.models.HttpMethod;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;


/**
 * @ClassName : SecutiryConfig  //类名
 * @Description : Security全局配置类  //描述
 * @Author : zpc20 //作者
 * @Date: 2023/11/2  9:44
 */

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
public class SecutiryConfig extends WebSecurityConfigurerAdapter {
       @Autowired
       LoginFailureHandler loginFailureHandler;
       @Autowired
       LoginSuccessHandler loginSuccessHandler;
       @Autowired
       LogoutSuccessHandler logoutSuccessHandler;
       @Autowired
       JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
       @Autowired
       AccessDenieHandler accessDenieHandler;
       @Autowired
       UserDetailServiceImpl userDetailService;
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
       @Bean
       public  JwtAuthenticationFilter jwtAuthenticationFilter() throws  Exception{
              return new JwtAuthenticationFilter(authenticationManager());
       }

       /**
        * @Param :  URL_WHITELIST
        * @Description : 放行路由
        * @Date: 2023/11/2
        */
       private static final String[] URL_WHITELIST = {
               // @Description : 放行头像资源映射 zpc20 2023/11/4 11:36
               "/uploadsImg/**",
               // @Description : 放行注册接口 zpc20 2023/11/4 11:37
               "/user/register",
               "/video/**",
               //放行swagger资源路径
               "/doc.html",
               "/swagger-ui/**",
               "/favicon.ico",
               "/swagger-resources/**",
               "/webjars/**",
               "/*/api-docs",
               "/v3/**",
               "/druid/**"
       };




      // 自定义用户服务实现类
       @Override
       protected void configure(AuthenticationManagerBuilder auth) throws Exception {
              auth.userDetailsService(userDetailService).passwordEncoder(passwordEncoder());
       }

       @Override
       protected void configure(HttpSecurity http) throws Exception {
           http.cors().and().csrf().disable()
                      //登录配置
                      .formLogin()
                      .successHandler(loginSuccessHandler)
                      .failureHandler(loginFailureHandler)
                      // 登出配置
                      .and()
                      .logout()
                      .logoutSuccessHandler(logoutSuccessHandler)

                      // 禁用session
                      .and()
                      .sessionManagement()
                      .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                      // 配置拦截规则
                      .and()
                      .authorizeRequests()
                      .antMatchers(URL_WHITELIST).permitAll()
                      .anyRequest().authenticated()
                      // 异常处理
                      .and()
                      // 未登录处理类
                      .httpBasic().authenticationEntryPoint(jwtAuthenticationEntryPoint)
                      .and()
                      // 无权限处理类
                      .exceptionHandling()
                      .accessDeniedHandler(accessDenieHandler)
                      // 配置自定义过滤器
                      .and()
                      .addFilter(jwtAuthenticationFilter())
                       // TODO:验证码验证
                      // .addFilterBefore(UsernamePasswordAuthenticationFilter.class)
                      ;
       }


}
